package com.backend.aspect;

import com.backend.annotation.RequireRole;
import com.backend.service.rbac.UserRoleService;
import com.common.constant.MessageConstant;
import com.common.exception.RoleException;
import com.common.threadlocal.UserLocal;
import com.pojo.dto.UserDTO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Component
@Aspect
@Slf4j
@Order(1)
public class RequireRoleAspect {
    @Autowired
    UserRoleService userRoleService;
    /**
     * 切入点
     */
    @Pointcut("execution(* com.backend..*.*(..)) && @annotation(com.backend.annotation.RequireRole)")
    public void requireRolePointCut(){}

    /**
     * 前置通知,在通知中进行角色的判断
     */
    @Before("requireRolePointCut()")
    public void requireRole(JoinPoint joinPoint) {
        log.info("开始校验角色");
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        RequireRole annotation = signature.getMethod().getAnnotation(RequireRole.class);
        String[] roles = annotation.value();
        if (roles == null || roles.length == 0) {
            return ;
        }
        UserDTO userDTO = UserLocal.getCurrentUserDTO();
        Long userId = userDTO.getId();
        List<String> userRoles = userRoleService.getRolesByUserId(userId);
        if (userRoles == null || userRoles.isEmpty()) {
            throw new RoleException(MessageConstant.NOT_HAVA_ROLES);
        }
        Set<String> userRolesSet = new HashSet<>(userRoles);
        for (int i = 0; i < roles.length; i ++) {
            if (userRolesSet.contains(roles[i])) {
                log.info(MessageConstant.ROLES_ENOUGH);
                return ;
            }
        }
        throw new RoleException(MessageConstant.NOT_ENOUGH_ROLES);
    }
}
